//
//  View+Ex.swift
//  TSLiveWallpaper
//
//  Created by 100Years on 2024/12/20.
//


import UIKit

public extension UIView {

    
    /// 增加渐变背景，需要先确定当前 view 的 frame
    /// - Parameters:
    ///   - colors: 渐变背景颜色数组
    ///   - startPoint: 渐变启示位置
    ///   - endPoint: 渐变结束位置
    ///   - layerSize: 指定 layer 的 size，否则和自己当前一样大
    public func addGradientBg(colors: [CGColor],
                       startPoint: CGPoint = .zero,
                       endPoint: CGPoint = CGPoint(x: 1, y: 1),
                       layerSize: CGSize? = nil) {
        let gl = CAGradientLayer()
        gl.colors = colors
        gl.startPoint = startPoint
        gl.endPoint = endPoint
        gl.frame = CGRect(origin: .zero, size: layerSize ?? self.bounds.size)
        gl.zPosition =  -1 // 将 gradientLayer 放在底层
        layer.insertSublayer(gl, at: 0)
    }
    
    /// 慎用
    /// 给 view 增加圆角阴影，会改变视图结构，慎用，
    /// 需add 且确定frame后再调用
    /// > Note: 慎用
    /// - Parameters:
    ///   - cornerRadius: 视图圆角
    ///   - shadowColor: 阴影颜色
    ///   - shadowOffset: 阴影偏移量
    ///   - shadowRadius: 阴影扩散距离
    ///   - shadowOpacity: 阴影透明度
    @discardableResult
    public func addCornerRadiusShadow(cornerRadius: CGFloat,
                               shadowColor: CGColor?,
                               shadowOffset: CGSize,
                               shadowRadius: CGFloat,
                               shadowOpacity: Float) -> UIView? {
        guard let supView = superview else {
            debugPrint("必须要先add，且确定了frame")
            return nil
        }
        
        let frame = self.frame
        
        let shadowView = UIView()
        shadowView.frame = frame
        shadowView.layer.shadowColor = shadowColor
        shadowView.layer.shadowOffset = shadowOffset
        shadowView.layer.shadowOpacity = shadowOpacity
        shadowView.layer.shadowRadius = shadowRadius
        
        supView.insertSubview(shadowView, belowSubview: self)
        
        shadowView.addSubview(self)
        self.frame = CGRect(origin: .zero, size: frame.size)
        self.clipsToBounds = false
        self.layer.masksToBounds = true
        self.layer.cornerRadius = cornerRadius
        
        return shadowView
        
    }
    
    

    /// 给 view 增加阴影
    /// - Parameters:
    ///   - cornerRadius: 视图圆角
    ///   - shadowColor: 阴影颜色
    ///   - shadowOffset: 阴影偏移量
    ///   - shadowRadius: 阴影扩散距离
    ///   - shadowOpacity: 阴影透明度
    @discardableResult
    public func addShadow(shadowColor: CGColor?,
                          shadowOffset: CGSize,
                          shadowRadius: CGFloat,
                          shadowOpacity: Float){
        layer.shadowColor = shadowColor
        layer.shadowOffset = shadowOffset
        layer.shadowOpacity = shadowOpacity
        layer.shadowRadius = shadowRadius
    }
}

public extension UIView {

    public enum MaskContentMode {
            case scaleToFill
            case scaleAspectFit
            case scaleAspectFill
        }

        /// 设置图片蒙版，支持指定 `contentMode` 和缩小比例
        /// - Parameters:
        ///   - image: 用作蒙版的图片
        ///   - contentMode: 蒙版的内容模式
        ///   - scaleFactor: 缩小比例，默认 1.0 表示不缩放，0.8 表示缩小为 80%
    public func setImageMask(image: UIImage, contentMode: MaskContentMode = .scaleAspectFit, scaleFactor: CGFloat = 1.0) {
            guard scaleFactor > 0 && scaleFactor <= 1 else {
                print("Invalid scaleFactor. It must be in the range (0, 1].")
                return
            }
            
            // 创建一个 CALayer 来作为蒙版
            let maskLayer = CALayer()
            maskLayer.contents = image.cgImage
            
            // 计算蒙版的 frame
            let viewSize = self.bounds.size
            let imageSize = image.size
            
            var maskFrame: CGRect = .zero
            
            switch contentMode {
            case .scaleToFill:
                // 拉伸填充整个视图
                maskFrame = CGRect(origin: .zero, size: viewSize)
                
            case .scaleAspectFit:
                // 按比例缩放，适配视图并居中
                let aspectWidth = viewSize.width / imageSize.width
                let aspectHeight = viewSize.height / imageSize.height
                let aspectRatio = min(aspectWidth, aspectHeight) // 按比例适配
                
                let scaledWidth = imageSize.width * aspectRatio * scaleFactor
                let scaledHeight = imageSize.height * aspectRatio * scaleFactor
                let xOffset = (viewSize.width - scaledWidth) / 2
                let yOffset = (viewSize.height - scaledHeight) / 2
                
                maskFrame = CGRect(x: xOffset, y: yOffset, width: scaledWidth, height: scaledHeight)
                
            case .scaleAspectFill:
                // 按比例缩放，填充视图并裁剪多余部分
                let aspectWidth = viewSize.width / imageSize.width
                let aspectHeight = viewSize.height / imageSize.height
                let aspectRatio = max(aspectWidth, aspectHeight) // 按比例填充
                
                let scaledWidth = imageSize.width * aspectRatio * scaleFactor
                let scaledHeight = imageSize.height * aspectRatio * scaleFactor
                let xOffset = (viewSize.width - scaledWidth) / 2
                let yOffset = (viewSize.height - scaledHeight) / 2
                
                maskFrame = CGRect(x: xOffset, y: yOffset, width: scaledWidth, height: scaledHeight)
            }
            
            maskLayer.frame = maskFrame
            
            // 设置蒙版
            self.layer.mask = maskLayer
        }
}


// Frame
public extension UIView {
    
    var viewController: UIViewController? {
        var next = superview
        while next != nil {
            let nextResponder = next?.next
            if nextResponder is UINavigationController ||
                nextResponder is UIViewController {
                return nextResponder as? UIViewController
            }
            next = next?.superview
        }
        return nil
    }
    
    func convertedToImage(rect: CGRect = .zero) -> UIImage? {
        var size = bounds.size
        var origin = bounds.origin
        if !size.equalTo(rect.size) && !rect.isEmpty {
            size = rect.size
            origin = CGPoint(x: -rect.minX, y: -rect.minY)
        }
        let format = UIGraphicsImageRendererFormat()
        format.opaque = false
        format.scale = UIScreen._scale
        let renderer = UIGraphicsImageRenderer(size: size, format: format)
        let image = renderer.image { context in
            drawHierarchy(in: CGRect(origin: origin, size: bounds.size), afterScreenUpdates: true)
        }
        return image
    }

    func toImage() -> UIImage? {
        let renderer = UIGraphicsImageRenderer(bounds: self.bounds)
        let image = renderer.image { context in
            self.layer.render(in: context.cgContext)
        }
        return image
    }
    
    func cornersRound(radius: CGFloat, corner: UIRectCorner) {
        if #available(iOS 11.0, *) {
            layer.cornerRadius = radius
            layer.maskedCorners = corner.mask
            self.clipsToBounds = true
        } else {
            let path = UIBezierPath(
                roundedRect: bounds,
                byRoundingCorners: corner,
                cornerRadii: CGSize(width: radius, height: radius)
            )
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            layer.mask = mask
        }
    }
}

extension UIRectCorner {
    var mask: CACornerMask {
        switch self {
        case .allCorners:
            return [.layerMinXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMinYCorner, .layerMaxXMaxYCorner]
        default:
            return .init(rawValue: rawValue)
        }
    }
}

public extension UIView {
    // 部分圆角（必须Frame已知）
    func makeCorner(_ corners: UIRectCorner, radius: CGFloat) {
        let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = path.cgPath
        layer.mask = maskLayer
    }
}

public extension UIView {
    /// 为视图添加高斯模糊效果
    /// - Parameters:
    ///   - blurRadius: 模糊半径（默认 10.0）
    ///   - fillColor: 填充颜色（可选，默认透明）
    func applyGaussianBlur(blurRadius: CGFloat = 10.0, fillColor: UIColor? = nil) {
        // 移除已有的模糊效果
        self.removeBlurEffect()
        
        // 创建模糊效果
        let blurEffect = UIBlurEffect(style: .light)
        let blurView = UIVisualEffectView(effect: blurEffect)
        blurView.frame = self.bounds
        blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        
        // 设置模糊强度
        if blurRadius != 10.0 {
            let blurAnimator = CABasicAnimation(keyPath: "inputRadius")
            blurAnimator.fromValue = blurRadius
            blurAnimator.toValue = blurRadius
            blurAnimator.duration = 0
            blurView.layer.add(blurAnimator, forKey: nil)
        }
        
        // 如果指定了填充颜色，添加一个覆盖视图
        if let color = fillColor {
            let colorOverlay = UIView(frame: self.bounds)
            colorOverlay.backgroundColor = color
            colorOverlay.autoresizingMask = [.flexibleWidth, .flexibleHeight]
            colorOverlay.isUserInteractionEnabled = false
            blurView.contentView.addSubview(colorOverlay)
        }
        
        self.addSubview(blurView)
    }
    
    /// 移除模糊效果
    func removeBlurEffect() {
        for subview in subviews {
            if subview is UIVisualEffectView {
                subview.removeFromSuperview()
            }
        }
    }
    
}

public extension UIView {
    static func creatColor(color:UIColor) -> UIView {
        let view = UIView()
        view.backgroundColor = color
        return view
    }
}


public extension UIView {
    func removeAllSubViews() {
        subviews.forEach { subview in
            subview.removeFromSuperview()
        }
    }
    
    
    func layoutCompleted(_ completion: @escaping () -> Void) {
        self.layoutIfNeeded()
        DispatchQueue.main.async {
            completion()
        }
    }
}


public func kGetSubFrame(superSize: CGSize, subViewSize: CGSize, contentMode: UIView.ContentMode = .scaleAspectFit, scaleFactor: CGFloat = 1.0)-> CGRect {
    guard scaleFactor > 0 && scaleFactor <= 1 else {
        print("Invalid scaleFactor. It must be in the range (0, 1].")
        return CGRect(origin: .zero, size: superSize)
    }
    
    var maskFrame: CGRect = .zero
    switch contentMode {
    case .scaleToFill:
        // 拉伸填充整个视图
        maskFrame = CGRect(origin: .zero, size: superSize)
        
    case .scaleAspectFit:
        // 按比例缩放，适配视图并居中
        let aspectWidth = superSize.width / subViewSize.width
        let aspectHeight = superSize.height / subViewSize.height
        let aspectRatio = min(aspectWidth, aspectHeight) // 按比例适配
        
        let scaledWidth = subViewSize.width * aspectRatio * scaleFactor
        let scaledHeight = subViewSize.height * aspectRatio * scaleFactor
        let xOffset = (superSize.width - scaledWidth) / 2
        let yOffset = (superSize.height - scaledHeight) / 2
        
        maskFrame = CGRect(x: xOffset, y: yOffset, width: scaledWidth, height: scaledHeight)
        
    case .scaleAspectFill:
        // 按比例缩放，填充视图并裁剪多余部分
        let aspectWidth = superSize.width / subViewSize.width
        let aspectHeight = superSize.height / subViewSize.height
        let aspectRatio = max(aspectWidth, aspectHeight) // 按比例填充
        
        let scaledWidth = subViewSize.width * aspectRatio * scaleFactor
        let scaledHeight = subViewSize.height * aspectRatio * scaleFactor
        let xOffset = (superSize.width - scaledWidth) / 2
        let yOffset = (superSize.height - scaledHeight) / 2
        
        maskFrame = CGRect(x: xOffset, y: yOffset, width: scaledWidth, height: scaledHeight)
    default:
        maskFrame = CGRect(origin: .zero, size: superSize)
    }
    
    return maskFrame
}


public extension UIView {
    /// 添加渐变色边框
    /// - Parameters:
    ///   - colors: 渐变色数组
    ///   - width: 边框宽度
    ///   - radius: 圆角半径（nil 时使用视图的现有圆角）
    ///   - startPoint: 渐变起点 (默认从左到右)
    ///   - endPoint: 渐变终点 (默认从左到右)
    func addGradientBorder(
        colors: [UIColor],
        width: CGFloat = 3,
        radius: CGFloat? = nil,
        startPoint: CGPoint = CGPoint(x: 0, y: 0.5),
        endPoint: CGPoint = CGPoint(x: 1, y: 0.5)
    ) {
        // 移除旧的渐变边框
        removeGradientBorder()
        
        let gradientLayer = CAGradientLayer()
        gradientLayer.name = "GradientBorder"
        gradientLayer.frame = bounds
        gradientLayer.colors = colors.map { $0.cgColor }
        gradientLayer.startPoint = startPoint
        gradientLayer.endPoint = endPoint
        
        let cornerRadius = radius ?? layer.cornerRadius
        let path = UIBezierPath(
            roundedRect: bounds.insetBy(dx: width/2, dy: width/2),
            cornerRadius: cornerRadius
        )
        
        let shapeLayer = CAShapeLayer()
        shapeLayer.name = "GradientBorderMask"
        shapeLayer.path = path.cgPath
        shapeLayer.lineWidth = width
        shapeLayer.fillColor = nil
        shapeLayer.strokeColor = UIColor.black.cgColor
        
        gradientLayer.mask = shapeLayer
        layer.addSublayer(gradientLayer)
    }
    
    /// 更新渐变色边框的frame（在layoutSubviews中调用）
    func updateGradientBorder() {
        guard let gradientLayer = layer.sublayers?.first(where: { $0.name == "GradientBorder" }) as? CAGradientLayer,
              let shapeLayer = gradientLayer.mask as? CAShapeLayer else {
            return
        }
        
        gradientLayer.frame = bounds
        
        let width = shapeLayer.lineWidth
        let cornerRadius = layer.cornerRadius
        let path = UIBezierPath(
            roundedRect: bounds.insetBy(dx: width/2, dy: width/2),
            cornerRadius: cornerRadius
        )
        
        shapeLayer.path = path.cgPath
    }
    
    /// 移除渐变色边框
    func removeGradientBorder() {
        layer.sublayers?.filter { $0.name == "GradientBorder" }.forEach {
            $0.removeFromSuperlayer()
        }
    }
}


public extension UIView {
    /// 移除视图上的所有Layer（保留视图自身的layer）
    func removeAllSublayers() {
        layer.sublayers?.forEach { $0.removeFromSuperlayer() }
    }
    
    /// 移除特定类型的所有Layer
    func removeSublayers<T: CALayer>(ofType layerType: T.Type) {
        layer.sublayers?
            .filter { $0.isKind(of: layerType) }
            .forEach { $0.removeFromSuperlayer() }
    }
}

public extension UIView {
    /// 移除所有手势识别器
    func removeAllGestureRecognizers() {
        gestureRecognizers?.forEach { gesture in
            removeGestureRecognizer(gesture)
        }
    }
}

public extension UIView {
    func asImage(opaque: Bool = false) -> UIImage {
        let format = UIGraphicsImageRendererFormat()
        format.opaque = opaque
        let renderer = UIGraphicsImageRenderer(bounds: bounds, format: format)
        return renderer.image { _ in
            drawHierarchy(in: bounds, afterScreenUpdates: true)
        }
    }
}
public extension UIView {
    /// 递归查找特定 tag 的父视图
    func findSuperview(withTag tag: Int) -> UIView? {
        var parent: UIView? = self.superview
        while let current = parent {
            if current.tag == tag {
                return current
            }
            parent = current.superview
        }
        return nil
    }
    
    /// 查找最顶层（距离当前视图最远）的 tag=100 的父视图
    func findFarthestSuperview(withTag tag: Int) -> UIView? {
        var farthestMatch: UIView?
        var currentView: UIView? = self.superview
        
        while let view = currentView {
            if view.tag == tag {
                // 更新为当前找到的（由于是向上遍历，第一个遇到的其实是离得最远的）
                farthestMatch = view
            }
            currentView = view.superview
        }
        
        return farthestMatch
    }
    
}
